feat: implement InventoryComponent for Epic 5.2#142
Conversation
- Add InventoryComponent with AddItem, RemoveItem, GetQuantity methods - Add HasSufficientQuantity helper for checking material availability - Immutable record pattern following codebase conventions - Comprehensive test coverage (11 tests) including edge cases Refs #41
Recommended Persona Reviews💻 .NET Specialist - C# code changes detected See docs/roles/ for persona details. Danger analysis complete for feat: implement InventoryComponent for Epic 5.2. 3 files changed, 3 commits. |
mcj-coder
left a comment
There was a problem hiding this comment.
Code Review: Epic 5.2 - InventoryComponent
Strengths ✅
- Clean immutable design using
sealed recordpattern - Complete test coverage (11 tests, all passing)
- Zero warnings with
--warnaserror - Clear API with intuitive methods
- Proper error handling for insufficient quantities
Critical Issues ❌
1. Missing Equality Implementation
Location: InventoryComponent.cs
Problem: The sealed record doesn't override Equals() and GetHashCode() for proper dictionary comparison. Default record equality compares dictionary references, not contents.
Why critical: This will cause incorrect equality comparisons when two inventories with the same contents are compared, breaking state management and change detection.
Fix: Add custom Equals() and GetHashCode() following the pattern in ClassProgressCollection.cs (lines 162-188).
Important Issues ⚠️
2. Missing Input Validation
Location: InventoryComponent.cs:36, :48
Problem: Neither AddItem nor RemoveItem validate that quantity is positive. This allows negative quantities to bypass validation.
Fix: Add guard clauses:
if (quantity <= 0)
{
throw new ArgumentOutOfRangeException(nameof(quantity),
"Quantity must be positive.");
}Missing tests: Need tests for negative and zero quantity scenarios.
3. Missing GetAll() Method
Problem: No way to enumerate all materials in inventory. ClassProgressCollection provides GetAll() but InventoryComponent doesn't.
Why important: Future systems will need this for UI display, weight/value calculations, crafting material checks, and serialization.
Fix: Add:
public IReadOnlyDictionary<MaterialId, int> GetAll() => _items;Minor Suggestions 💡
- Add immutability test (verify operations return new instances)
- Add
HasSufficientQuantityedge case tests (zero/negative quantities) - Consider documenting capacity limits design decision
Assessment
Status: Request Changes
Verdict: Core design is excellent and aligns with project patterns. The Critical equality issue must be fixed to prevent state management bugs. Important issues (validation, GetAll) should also be addressed for completeness and future-proofing.
Next Steps: Fix the 3 key issues above, then this will be ready to merge.
… to InventoryComponent Addresses code review feedback from PR #142: 1. Critical: Implement custom Equals() and GetHashCode() - Follows pattern from ClassProgressCollection (lines 162-188) - Compares dictionary contents, not references - Prevents state management bugs 2. Important: Add input validation for AddItem/RemoveItem - Validates quantity > 0 in both methods - Throws ArgumentOutOfRangeException for invalid quantities - Prevents negative quantities bypassing validation 3. Important: Add GetAll() method - Returns IReadOnlyDictionary<MaterialId, int> - Enables UI display, serialization, and material checks - Aligns with ClassProgressCollection pattern Test coverage: - 11 new tests for equality, validation, GetAll, and immutability - All 456 tests passing, zero warnings Refs #41
Review Feedback AddressedThank you for the thorough review! I've implemented all three requested changes: 1. ✅ Custom Equality Implementation (Critical)
2. ✅ Input Validation (Important)
3. ✅ GetAll() Method (Important)
Additional Improvements
Ready for re-review! |
mcj-coder
left a comment
There was a problem hiding this comment.
Re-Review: All Issues Addressed ✅
Excellent work addressing all the review feedback! The implementation now follows project patterns and is production-ready.
Changes Verified
1. ✅ Critical: Equality Implementation (lines 96-124)
- Custom
Equals()compares dictionary contents, not references GetHashCode()uses ordered iteration for consistency- Follows ClassProgressCollection pattern exactly
- Tests confirm equal inventories are detected correctly
2. ✅ Important: Input Validation (lines 38-41, 56-59)
- Both
AddItemandRemoveItemvalidate quantity > 0 - Throws
ArgumentOutOfRangeExceptionfor invalid values - Prevents negative quantities bypassing validation
- Comprehensive test coverage for zero/negative cases
3. ✅ Important: GetAll() Method (line 93)
- Returns
IReadOnlyDictionary<MaterialId, int>as recommended - Enables UI display, serialization, and material checks
- Aligns with ClassProgressCollection pattern
- Tests verify correct behavior for empty and populated inventories
Test Coverage ✅
- 22 total tests (11 original + 11 new)
- Equality comparison (4 tests)
- Input validation (4 tests)
- GetAll() method (2 tests)
- Immutability verification (2 tests)
- All 456 tests passing, zero warnings
Quality Gates ✅
- ✅ All CI checks passed
- ✅ Zero compiler warnings
- ✅ Clean build
- ✅ Comprehensive test coverage
- ✅ Follows project patterns
Status: Approved - Ready to merge!
Great job implementing the fixes methodically and thoroughly.
Summary
Adds InventoryComponent for character inventory management with add, remove, and query operations. Enables characters to track materials with immutable operations following codebase patterns.
Issue
Closes #41
Changes
AddItem(materialId, quantity)- adds or increments material quantityRemoveItem(materialId, quantity)- removes material with validationGetQuantity(materialId)- retrieves current quantity (0 if not present)HasSufficientQuantity(materialId, quantity)- checks availabilityTesting
Test Coverage
Test Output
Build Output
Notes
This PR recreates the InventoryComponent work from the closed PR #140, now properly opened from the Contributor account (martincjarvis) as required by the workflow.
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com